package cn.lblbc.appassit.utils

import android.content.Context
import cn.lblbc.appassit.model.AppInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream

class AppExporter(private val context: Context) {
    suspend fun exportApps(
        appList: List<AppInfo>,
        exportDirectory: String
    ): ExportResult = withContext(Dispatchers.IO) {

        val exportDir = File(exportDirectory)
        if (!exportDir.exists()) {
            exportDir.mkdirs()
        }

        var successCount = 0
        var failCount = 0
        val failedApps = mutableListOf<String>()

        for (appInfo in appList) {
            try {
                val sourceFile = File(appInfo.apkPath)
                if (sourceFile.exists()) {
                    val fileName = generateFileName(appInfo,null)
                    val targetFile = File(exportDir, fileName)
                    copyFile(sourceFile, targetFile)
                    successCount++
                } else {
                    failCount++
                    failedApps.add("${appInfo.appName} - APK文件不存在")
                }
            } catch (e: Exception) {
                failCount++
                failedApps.add("${appInfo.appName} - ${e.message}")
            }
        }

        ExportResult(
            success = failCount == 0,
            exportPath = exportDir.absolutePath,
            totalCount = appList.size,
            successCount = successCount,
            failCount = failCount,
            failedApps = failedApps
        )
    }

    suspend fun exportApp(
        appInfo: AppInfo,
        exportDirectory: String,
        customFileName: String? = null
    ): ExportResult = withContext(Dispatchers.IO) {

        val exportDir = File(exportDirectory)
        if (!exportDir.exists()) {
            exportDir.mkdirs()
        }

        var successCount = 0
        var failCount = 0
        val failedApps = mutableListOf<String>()

        var fileName = ""
        // 导出APK文件
        try {
            val sourceFile = File(appInfo.apkPath)
            if (sourceFile.exists()) {
                fileName = generateFileName(appInfo, customFileName)
                val targetFile = File(exportDir, fileName)
                copyFile(sourceFile, targetFile)
                successCount++
            } else {
                failCount++
                failedApps.add("${appInfo.appName} - APK文件不存在")
            }
        } catch (e: Exception) {
            failCount++
            failedApps.add("${appInfo.appName} - ${e.message}")
        }

        ExportResult(
            success = failCount == 0,
            exportPath = exportDir.absolutePath + "/" + fileName,
            totalCount = 1,
            successCount = successCount,
            failCount = failCount,
            failedApps = failedApps
        )
    }

    private fun copyFile(source: File, target: File) {
        FileInputStream(source).use { input ->
            FileOutputStream(target).use { output ->
                input.copyTo(output)
            }
        }
    }

    private fun generateFileName(appInfo: AppInfo, customFileName: String?): String {
        // 如果没有提供自定义文件名，使用默认格式
        if (customFileName.isNullOrBlank()) {
            return "${appInfo.appName}.apk"
        }

        // 使用用户提供的文件名
        var fileName = customFileName

        // 确保文件名以.apk结尾
        if (!fileName.endsWith(".apk", ignoreCase = true)) {
            fileName += ".apk"
        }

        // 清理文件名中的非法字符
        fileName = fileName.replace(Regex("[<>:\"/\\\\|?*]"), "_")

        // 确保文件名不以点开头
        if (fileName.startsWith(".")) {
            fileName = fileName.substring(1)
        }

        // 确保文件名不为空
        if (fileName.isBlank()) {
            return "${appInfo.appName}.apk"
        }

        return fileName
    }

    data class ExportResult(
        val success: Boolean,
        val exportPath: String,
        val totalCount: Int,
        val successCount: Int,
        val failCount: Int,
        val failedApps: List<String>
    )
}